import md5 from 'md5'
import { Toast, ShowLoading, HideLoading, GetStorage, ClearStorage, FileSystemManager } from './wx.public'
import { EncryptionToDecrypt, getSpecifyTxt, AliyunOSSUpdateData } from './util'
//   let baseURL,payURL,loginURL;

const envVersion = wx.getAccountInfoSync().miniProgram.envVersion, MQ = [], DWMQ = [];
const evn = {
    develop: { //开发版
        baseURL: 'http://rwapitest.cheeseword.com',
        payURL: 'https://xxx.com',
        loginURL: 'http://rwapitest.cheeseword.com',
    },
    trial: { //体验版
        baseURL: 'https://xxx.com',
        payURL: 'https://xxx.com',
        loginURL: 'https://xxx.com',
    },
    release: { //	正式版
        baseURL: 'https://xxx.com',
        payURL: 'https://xxx.com',
        loginURL: 'https://xxx.com',
    }
}


const dwadd = `${wx.env.USER_DATA_PATH}/111`;


export class RequestHttp {

    static successCode = [200, "200",]

    static abnormalCode = [null, undefined, '', ' ', 'null', 'undefined', 'Null', 'Undefined']

    static RetryUpdateTimes = 0; // 上次错误重试次数

    /**
     * http 请求参数配置
     * @param {*} url url 地址
     * @param {*} data 发送数据
     * @param {*} method 请求方式，默认 POTS
     * @param {*} Loading  数据请求中是否现在加载
     * @param {*} baseType 请求地址 默认 baseType 可选 payURL | loginURL 
     * @param {*} dataAll 是否返回所有数据 默认 false
     * @param {*} verifyData 是否返回所有数据 默认 false
     */
    static request(url, data, method = "POST", Loading = false, baseType = "baseURL", dataAll = false, verifyData = false) {

        const token = GetStorage('token');

       if(token == null){
            ClearStorage()
            wx.switchTab({
              url: 'pages/master/my_index/my_index',
            })
       }
        const href = url.startsWith('https://') || url.startsWith('http://')

        url = href ? url : url = evn[envVersion][baseType] + url
        // if (href) {
        //     url = url
        // } else {
        //     url = evn[envVersion][baseType] + url
        //     // baseType === "baseURL" && (url = evn[envVersion][baseType] + url)
        //     // baseType === "payURL" && (url = evn[envVersion][baseType] + url)
        //     // baseType === "loginURL" && (url = evn[envVersion][baseType] + url)
        // }


        // 部分接口放行
        //   const release = ['wxmini/auth_login', 'wxmini/quick_login', 'token/getToken', 'userCenter/send_smscode', 'userCenter/code_login'];
        //   if (RequestHttp.successCode.includes(getStorage('MiaoShareToken')) || RequestHttp.successCode.includes(token) || RequestHttp.successCode.includes(openId))
        //   {
        //     if (!release.find((srt) => url.includes(srt)))
        //     {
        //       ClearStorage()
        //       wx.navigateTo({ url: "/pages/my/authorize/authorize" })
        //       return false
        //     }
        //   }
        var start = wx.getPerformance().now();
        return new Promise((resolve, reject) => {
            //   const methods = ['get', 'GTE', 'POST', 'post']
            //   if (arguments.length === 3) {      
            //     data = method
            //     method = (methods.includes(method) ? method : 'post');
            //   }

            // console.log(MQ, 'app.MQ');
            const is = MQ.find(u => verifyData ? u.url === url : u.url === url && u.data === JSON.stringify(data)),
                indexId = MQ.findIndex(u => u.url === url && u.data === JSON.stringify(data));
            // console.log('开始', is, MQ);
            if (is) {
                is.request.abort();
                MQ.splice(indexId, 1)
            }
            let userLogin = getApp().globalData.userLogin
            const requestTask = wx.request({
                url,
                data,
                header: {
                    "Accept": "application/json",
                    "Content-Type": "application/json",
                    "channel": "AppStore",
                    "system": 0,
                    "token": token,
                    "version": "2.8.6",
                    "x-uniqeId": "BB2FD859-2E43-460E-8AC5-E51728386C11",
                },
                method: method,
                dataType: 'json',
                success: (res) => {
                    const is = MQ.find(u => verifyData ? u.url === url : u.url === url && u.data === JSON.stringify(data))
                    const indexId = MQ.findIndex(u => u.url === url && u.data === JSON.stringify(data))
                    console.log('结束', is, MQ, res);
                    is && MQ.splice(indexId, 1)
                    Loading && HideLoading()
                    const { statusCode, data } = res, // http 回来数据解构
                        handleData = RequestHttp.success(data),
                        dataBox = typeof handleData === 'string' ? JSON.parse(handleData) : handleData;
                    if (href) { // 传入请求是全域名就不做任何处理
                        resolve(data)
                    } else {
                        dataAll ? resolve(data) : RequestHttp.successCode.includes(statusCode) && dataBox ? resolve(dataBox) : reject(data)
                    }

                },
                fail: (err) => {
                    reject(0)
                },
                complete() {
                    var end = wx.getPerformance().now();
                    console.warn(`taxiRequest函数，接口请求url地址，${url},请求参数：${JSON.stringify(data)}，接口耗时`, `${end - start}ms`)
                }
            })
            MQ.push({
                url,
                data: JSON.stringify(data),
                request: requestTask
            })
        })
    }
    /**
     * @param {*} filePath 
     * @param {*} name 
     * @param {*} Loading 
     * @param {*} formData 
     */
    static uploadFile(filePath, Loading = false, formData = {}) {
        return new Promise((resolve, reject) => {
            let { MiniProgramConfig, AliyunOSSTSTConfig } = getApp().globalData
            const { uploadAliyunOSSURL, AliyunOSStoragePath } = MiniProgramConfig;
            const { AccessKeyId, AccessKeySecret, SecurityToken } = AliyunOSSTSTConfig
            Loading && ShowLoading()

            const { suffix } = getSpecifyTxt(filePath)
            const key = `${AliyunOSStoragePath}${new Date().getTime()}${Math.floor(Math.random() * 150)}${suffix}`;
            const formData = {
                key,
                'success_action_status': '200',
                ...AliyunOSSUpdateData({ AccessKeyId, AccessKeySecret, SecurityToken })
            }
            wx.uploadFile({
                url: uploadAliyunOSSURL,//开发者服务器 url
                filePath: filePath,//要上传文件资源的路径
                name: 'file',//必须填file
                formData,
                success: async (res) => {
                    if (res.statusCode != 200) {
                        if (res.statusCode === 403 || Object.keys(getApp().globalData.AliyunOSSTSTConfig).length === 0) { // 处理为重新请求STS服务
                            const Secret = await RequestHttp.request('https://rwapi.cheeseword.com/v1/Alists/getStsToken', null, 'get')
                            console.log('Secret', Secret)
                            if (Secret.StatusCode === 200) {
                                getApp().globalData.AliyunOSSTSTConfig = Secret
                            } else {
                                reject('上传获取STS服务错误');
                            }
                        }
                        if (RequestHttp.RetryUpdateTimes <= 2) {
                            RequestHttp.RetryUpdateTimes++
                            const retry = await RequestHttp.uploadFile(filePath, Loading, formData).catch(retryErr => reject(retryErr))
                            resolve(retry)
                        } else {
                            console.log('错误重试完3次！')
                            reject('上传错误');
                        }
                    }
                    resolve(uploadAliyunOSSURL + key);
                },
                fail: function (err) {
                    err.wxaddinfo = uploadAliyunOSSURL;
                    console.log(err, '上传错误');
                    reject(err);
                },
            })
        })
    }

    /**
     * 加载远程字体
     * @param {*} url 字体网络地址 建议格式为 TTF 和 WOFF，WOFF2 在低版本的iOS上会不兼容。
     * @param {*} fontFamily 应用到css的字体名称 不传默认使用链接后面名称
     */
    static loadFontFace(url, fontFamily) {
        const Start = url.lastIndexOf('/'), End = url.lastIndexOf('.'), family = url.slice(Start + 1, End);
        if (Start == -1 || End == -1) {
            throw `解析 ${url}的字体名称异常，需要第二个参数为字体名称`
        }
        return new Promise((resolve, reject) => {
            wx.loadFontFace({
                family: fontFamily || family,
                global: true,
                source: `url(${url})`,
                scopes: ['native', 'webview'],
                complete(resData) {
                    resolve(resData)
                }
            })
        })
    }

    /**
     * 下载内容
     * @param {string} url 下载内容地址
     */
    static downloadFile(url) {
        const start = wx.getPerformance().now(), fs = wx.getFileSystemManager(), THIS = this;
        return new Promise(async (resolve, reject) => {
            // console.log(DWMQ, 'app.DWMQ');
            const is = DWMQ.find(u => u.url === url),
                indexId = DWMQ.findIndex(u => u.url === url),
                newFIleName = md5(url);
            // console.log('开始下载', is, DWMQ);
            if (is) {
                is.downloadFile.abort();
                DWMQ.splice(indexId, 1)
            }
            const Start = url.lastIndexOf('/'), End = url.length, fileName = url.slice(Start + 1, End);
            const getHostFiles = await FileSystemManager.readdir(dwadd).catch(err => {
                return reject({ errMsg: '打开本地目录获取内容失败', ...err })
            })
            if (getHostFiles.length > 0) {
                const getaudioURl = getHostFiles.find(audioU => audioU === newFIleName);
                if (getaudioURl) {
                    const FilePath = `${dwadd}/${newFIleName}`
                    return resolve({ LocalAddress: FilePath, fileName: getaudioURl, SaveFIleAddress: FilePath })
                }
            }
            const downloadTask = wx.downloadFile({
                url,
                filePath: `${dwadd}/${fileName}`,
                success: async (res) => {
                    const is = DWMQ.find(u => u.url === url)
                    const indexId = DWMQ.findIndex(u => u.url === url)
                    // console.log('结束下载', is, DWMQ, res);
                    is && DWMQ.splice(indexId, 1)
                    // 没有设置文件保存路径默认用 tempFilePath ，设置了保存就用 filePath
                    const { dataLength, errMsg, statusCode, tempFilePath, filePath } = res;
                    if (errMsg === 'downloadFile:ok' && statusCode === 200 && dataLength > 0) {
                        const saveFile = await FileSystemManager.fsSaveFile((tempFilePath || filePath), `${dwadd}/${newFIleName}`).catch(err => {
                            return reject(err)
                        })
                        if (saveFile.errMsg === 'saveFile:ok') {
                            /**
                             * LocalAddress 下载的位置目录
                             * fileName 文件名称
                             * SaveFIleAddress 保存文件地址
                             * savedFilePath 使用saveFile 保存位置
                             */
                            return resolve({ LocalAddress: tempFilePath || filePath, fileName: newFIleName, SaveFIleAddress: `${dwadd}/${newFIleName}`, savedFilePath: saveFile.savedFilePath })
                        }
                    }
                },
                fail(err) {
                    // console.log(err, '下载错误')
                    return reject(err)
                },
                complete() {
                    var end = wx.getPerformance().now();
                    console.warn(`taxiRequest函数，接口请求url地址，${url}，接口耗时`, `${end - start}ms`)
                }
            })
            DWMQ.push({
                url,
                downloadFile: downloadTask
            })
        })
    }

    /**
     * 解析成功内容并返回
     * @param {*} successData 
     */
    static success(successData) {
        const {
            code,
            data,
            message,
            isGz,
            msg
        } = successData;
        if (RequestHttp.successCode.includes(parseInt(code))) {
            return isGz === 1 ? EncryptionToDecrypt.unGzip(EncryptionToDecrypt.decryptionCryptoJS(data)) : EncryptionToDecrypt.decryptionCryptoJS(data);
        } else if (code === 1) {
            return isGz === 1 ? EncryptionToDecrypt.unGzip(EncryptionToDecrypt.decryptionCryptoJS(successData.data)) : EncryptionToDecrypt.decryptionCryptoJS(successData.data);
        } else if (code == 100) { // 渝客行授权认证 返回的 未绑定愉客行账号
            return isGz === 1 ? EncryptionToDecrypt.unGzip(EncryptionToDecrypt.decryptionCryptoJS(successData.data)) : EncryptionToDecrypt.decryptionCryptoJS(successData.data);
        } else if ([-2, 8001, 7001].includes(parseInt(code))) // 没有登陆或者token失效
        {
            ClearStorage()
            wx.redirectTo({
                url: '/pages/my/authorize/authorize'
            })
        } else {
            Toast(message || msg)
            return null
        }
    }
}

export const request = RequestHttp.request
export const uploadFile = RequestHttp.uploadFile
export const loadFontFace = RequestHttp.loadFontFace
export const downloadFile = RequestHttp.downloadFile